#include <iostream>
#include <stdio.h>
#include <cstring>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <fcntl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <unistd.h>
#include <thread>
void dump_hex(const unsigned char *p,int len)
{
    int i;
    char buf[128];
    int ret=0;
    for(i=0;i<len;i++){
        ret += sprintf(buf+ret,"%.2x ",*(p+i));
        if(i%16 == 15 )
        {
            printf("%s\n",buf);
            memset(buf,'\0',ret);
            ret = 0;
        }
    }
    
    if(ret)
        printf("%s\n",buf);
}

void receiveCanMessages(const char* interface) {
    int s;
    struct sockaddr_can addr;
    struct ifreq ifr;
    struct can_frame frame;
    // const int bufferLength = 16 * 1024;

    // 创建CAN原始套接字
    if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
        perror("Error while opening socket");
        return;
    }

    // 设置接口名
    strcpy(ifr.ifr_name, interface);
    if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
        perror("Error while getting interface index");
        close(s);
        return;
    }

    // 绑定套接字到指定的CAN接口
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("Error while binding socket");
        close(s);
        return;
    }

    // 设置为非阻塞模式以避免阻塞主线程
    fcntl(s, F_SETFL, O_NONBLOCK);

    while (true) {
        // 尝试读取CAN消息
        ssize_t bytesReceived = read(s, &frame, sizeof(frame));
        if (bytesReceived > 0) {
            std::cout << "Received: CAN ID=" << frame.can_id
                      << ", DLC=" << static_cast<int>(frame.can_dlc);
            // for(int i = 0; i < frame.can_dlc; ++i)
            //     std::cout << ", Data[" << i << "]=" << static_cast<int>(frame.data[i]);
            // std::cout << std::endl;
            dump_hex(frame.data,frame.can_dlc);
        }
        else if (bytesReceived == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
            perror("Error while reading from socket");
            break;
        }
        // 简单的延迟以避免CPU过度占用
        usleep(1000);
    }

    close(s);
}

int main() {
    std::thread receiver(receiveCanMessages, "vcan0");
    receiver.join();
    return 0;
}